home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: delta / whiteline CD Series - delta.iso / vision / grafics / programm / img2ps / source / image.c next >
Encoding:
C/C++ Source or Header  |  1995-11-25  |  8.8 KB  |  461 lines

  1. /*
  2.     image.c
  3.  
  4.         bibliothek zum laden von gem-ximage-dateien
  5.  
  6.     geschrieben von Th. Morus Walter
  7.  
  8.     (c) 1994/95 by Th. Morus Walter
  9. */
  10. #include <tos.h>
  11. #include <stdlib.h>
  12.  
  13. #include <image.h>
  14.  
  15. /*
  16.     int load_ximg(char *name,MFDB *mfdb,IMG_COLOR **coltab)
  17.     int load_img(char *name,MFDB *mfdb)
  18.  
  19. lade gem-image datei
  20.  
  21. rückgabewerte
  22.     0  -> ok
  23.     <0 -> os-error
  24.     >0 -> 3: format falsch
  25.        -> 2: speicher reicht nicht
  26.        -> 1: allg error
  27.  
  28. coltab wird auf 0l gesetzt wenn keine XIMG datei geladen wird
  29. speicher für bilddaten und farbtabelle wird mit malloc alloziert
  30.  
  31.     changes:
  32.         ⓪⑤.⓪①.①⑨⑨⑤  setze picture->fd_r1..fd_r3 auf 0
  33. */
  34.  
  35. #define BUF_SIZE        2048
  36.  
  37. static int f_id;
  38. static char *w_buf;
  39. static int z,z1;
  40. static long l;
  41.  
  42. static int init_get_byte(long len)
  43. {
  44.     l=len;
  45.     z=0;
  46.     w_buf=malloc(BUF_SIZE);
  47.     if ( !w_buf )
  48.         return IMG_MEMORY;
  49.     return IMG_OK;
  50. }
  51.  
  52. static int get_byte(char *byte)
  53. {
  54. long len;
  55. long ret;
  56.     if ( z==0 ) {
  57.         if ( l<BUF_SIZE ) {
  58.             len=l;
  59.         }
  60.         else {
  61.             len=BUF_SIZE;
  62.             l-=BUF_SIZE;
  63.         }
  64.         if ( (ret=Fread(f_id,len,w_buf))!=len ) {
  65.             if ( ret<0 )
  66.                 return (int)ret;
  67.             else
  68.                 return IMG_ERROR;
  69.         }
  70.         z=(int)len;
  71.         z1=0;
  72.     }
  73.     *byte=w_buf[z1];
  74.     z1++;
  75.     z--;
  76.     return IMG_OK;
  77. }
  78.  
  79. static int get_block(char *buf,int len)
  80. {
  81. int ret;
  82.  
  83.     for ( ; len>0; len-- )
  84.         if ( (ret=get_byte(buf++))!=IMG_OK )
  85.             return ret;
  86.     return IMG_OK;
  87. }
  88.  
  89. static int do_ld_img(char *buffer,char *line_buf,IMG_HEADER *head)
  90. {                /* return: <0 -> os-error, IMG_FORMAT falsches datenformat, IMG_ERROR tosfehler, 0 ok */
  91. char *line,*h,*h1;
  92. char byte,l_cnt,b_cnt;
  93. char muster[16];
  94. int lline_len,line_len;
  95. long pl_len;
  96. int planes,lines,bytes,i;
  97.  
  98.     line_len=head->pix_num/8;
  99.     if ( head->pix_num%8 )
  100.         line_len++;
  101.     lline_len=line_len*head->plane_num;
  102.     pl_len=(long)line_len*head->scan_num;
  103.     if ( line_len&1 )
  104.         pl_len+=head->scan_num;
  105.  
  106.     line=buffer;
  107.     h=line_buf;
  108.     bytes=lines=0;
  109.     l_cnt=1;        /* anzahl von zeilenwiederholungen */
  110.  
  111.     while (1) {
  112.         if ( bytes>=lline_len ) {    /* ganze zeile eingelesen */
  113.             for ( ; l_cnt>0; l_cnt-- ) {
  114.                 h1=line_buf;
  115.                 for ( planes=0; planes<head->plane_num; planes++ ) {
  116.                     for ( i=0,h=line+planes*pl_len; i<line_len; i++ )
  117.                         *h++=*h1++;
  118.                     if ( line_len&1 )
  119.                         *h++=0;
  120.                 }
  121.                 lines++;
  122.                 line+=line_len;
  123.                 if ( line_len&1 )
  124.                     line++;
  125.             }
  126.             if ( lines>=head->scan_num )
  127.                 return IMG_OK;
  128.             l_cnt=1;
  129.             h=line_buf;
  130.             bytes=0;
  131.         }
  132.  
  133.         if ( get_byte(&byte)!=IMG_OK )
  134.             return IMG_ERROR;
  135.         if ( byte==0 ) {
  136.             if ( get_byte(&byte)!=IMG_OK )
  137.                 return IMG_ERROR;
  138.             if ( byte==0 ) {
  139.                 if ( get_byte(&byte)!=IMG_OK )
  140.                     return IMG_ERROR;
  141.                 if ( byte!=0xFF )
  142.                     return IMG_FORMAT;
  143.                 if ( get_byte(&l_cnt)!=IMG_OK )
  144.                     return IMG_ERROR;
  145.             }
  146.             else {
  147.                 for ( i=0; i<head->pat_len; i++ )
  148.                     if ( get_byte(muster+i)!=IMG_OK )
  149.                         return IMG_ERROR;
  150.                 for ( ; byte>0; byte-- ) {
  151.                     for ( i=0; i<head->pat_len; i++ ) {
  152.                         *h++=muster[i];
  153.                         bytes++;
  154.                         if ( bytes>lline_len )
  155.                             return IMG_FORMAT;
  156.                     }
  157.                 }
  158.             }
  159.         }
  160.         else if ( byte==0x80 ) {
  161.             if ( get_byte(&b_cnt)!=IMG_OK )
  162.                 return IMG_ERROR;
  163.             for ( ; b_cnt>0; b_cnt-- ) {
  164.                 if ( get_byte(h++)!=IMG_OK )
  165.                     return IMG_ERROR;
  166.                 bytes++;
  167.                 if ( bytes>lline_len )
  168.                     return IMG_FORMAT;
  169.             }
  170.         }
  171.         else {
  172.           int set=0;
  173.             if ( byte&0x80 ) {
  174.                 byte&=0x7F;
  175.                 set=0xFF;
  176.             }
  177.             for ( ; byte>0; byte-- ) {
  178.                 *h++=set;
  179.                 bytes++;
  180.                 if ( bytes>lline_len )
  181.                     return IMG_FORMAT;
  182.             }
  183.         }
  184.     }
  185. }
  186.  
  187. static IMG_ERR do_load_ximg(IMG_HEADER *head,char *name,MFDB *picture,IMG_COLOR **coltab)
  188. {
  189. long len,llen;
  190. int line_len;
  191. IMG_ERR ret;
  192. char *line_buf;
  193. char byte;
  194.  
  195.     picture->fd_addr=0l;
  196.  
  197.     f_id=Fopen(name,0);
  198.     if ( f_id<0 )
  199.         return f_id;
  200.  
  201.     if ( (len=Fseek(0,f_id,2))<0 ) {
  202.         Fclose(f_id);
  203.         return (int)len;
  204.     }
  205.     if ( Fseek(0,f_id,0)!=0l ) {
  206.         Fclose(f_id);
  207.         return IMG_ERROR;
  208.     }
  209.  
  210.     if ( init_get_byte(len)!=IMG_OK )
  211.         return IMG_MEMORY;
  212.  
  213.     /*
  214.             lese header
  215.     */
  216.     if ( (ret=get_block((char*)head,(int)sizeof(IMG_HEADER)))!=IMG_OK ) {
  217.         Fclose(f_id);
  218.         return ret;
  219.     }
  220.  
  221.     head->head_len*=2;    /* head_len in bytes, nicht words */
  222.     len-=head->head_len;
  223.     head->head_len-=(int)sizeof(IMG_HEADER);
  224.  
  225.     *coltab=0l;
  226.     if ( head->head_len>sizeof(IMG_HEADER) ) {        /* zus. header überlesen */
  227.       struct {                                    /* ximg-header lesen */
  228.         long id;
  229.         int col_flag;
  230.       } ximg;
  231.       int col_len;
  232.  
  233.         if ( head->head_len>sizeof(ximg) ) {
  234.             if ( get_block((char*)&ximg,(int)sizeof(ximg))!=IMG_OK ) {
  235.                 Fclose(f_id);
  236.                 return IMG_ERROR;
  237.             }
  238.             head->head_len-=(int)sizeof(ximg);
  239.             if ( ximg.id=='XIMG' && ximg.col_flag==0 ) {
  240.                 col_len=(int)sizeof(IMG_COLOR)*1<<head->plane_num;
  241.                 *coltab=malloc(col_len);
  242.                 if ( *coltab==0l ) {
  243.                     Fclose(f_id);
  244.                     return IMG_MEMORY;
  245.                 }
  246.                 if ( col_len<=head->head_len ) {
  247.                     if ( get_block((char*)*coltab,col_len)!=IMG_OK ) {
  248.                         Fclose(f_id);
  249.                         return IMG_ERROR;
  250.                     }
  251.                     head->head_len-=(int)col_len;
  252.                 }
  253.                 else {
  254.                     free(*coltab);
  255.                 }
  256.             }
  257.         }
  258.     }
  259.  
  260.     if ( head->head_len>0 ) {
  261.         while ( head->head_len-- ) {
  262.             if ( (ret=get_byte(&byte))!=IMG_OK ) {
  263.                 Fclose(f_id);
  264.                 return ret;
  265.             }
  266.         }
  267.     }
  268.     else if ( head->head_len<0 ) {
  269.         Fclose(f_id);
  270.         return IMG_FORMAT;
  271.     }
  272.  
  273.     if ( head->plane_num>8 || head->pat_len>8 ) {
  274.         Fclose(f_id);
  275.         return IMG_FORMAT;
  276.     }
  277.  
  278.     picture->fd_h=head->scan_num;
  279.     picture->fd_nplanes=head->plane_num;
  280.     picture->fd_stand=1;
  281.     picture->fd_r1=picture->fd_r2=picture->fd_r3=0;
  282.  
  283.     line_len=head->pix_num/8;
  284.     if ( head->pix_num%8 )
  285.         line_len++;
  286.     picture->fd_wdwidth=line_len/2;
  287.     if ( line_len&1 )
  288.         picture->fd_wdwidth++;
  289.     
  290.     picture->fd_w=head->pix_num;
  291.  
  292.     len=(long)picture->fd_wdwidth*2*(long)head->scan_num*(long)head->plane_num;
  293.  
  294.     picture->fd_addr=malloc(len);
  295.     if ( picture->fd_addr==0l ) {
  296.         Fclose(f_id);
  297.         return IMG_MEMORY;
  298.     }
  299.  
  300.     llen=(long)head->pix_num*head->plane_num/8;
  301.     line_buf=malloc(llen);
  302.     if ( !line_buf ) {
  303.         Fclose(f_id);
  304.         return IMG_MEMORY;
  305.     }
  306.  
  307.     ret=do_ld_img(picture->fd_addr,line_buf,head);
  308.  
  309.     Fclose(f_id);
  310.     free(line_buf);
  311.     free(w_buf);
  312.  
  313.     return ret;
  314. }
  315.  
  316.  
  317. static IMG_ERR do_load_img(IMG_HEADER *head,char *name,MFDB *picture)
  318. {
  319. long len,llen;
  320. int line_len;
  321. IMG_ERR ret;
  322. char *line_buf;
  323. char byte;
  324.  
  325.     picture->fd_addr=0l;
  326.  
  327.     f_id=Fopen(name,0);
  328.     if ( f_id<0 )
  329.         return f_id;
  330.  
  331.     if ( (len=Fseek(0,f_id,2))<0 ) {
  332.         Fclose(f_id);
  333.         return (int)len;
  334.     }
  335.     if ( Fseek(0,f_id,0)!=0l ) {
  336.         Fclose(f_id);
  337.         return IMG_ERROR;
  338.     }
  339.  
  340.     if ( init_get_byte(len)!=IMG_OK )
  341.         return IMG_MEMORY;
  342.  
  343.     /*
  344.             lese header
  345.     */
  346.     if ( (ret=get_block((char*)head,(int)sizeof(IMG_HEADER)))!=IMG_OK ) {
  347.         Fclose(f_id);
  348.         return ret;
  349.     }
  350.  
  351.     head->head_len*=2;    /* head_len in bytes, nicht words */
  352.     len-=head->head_len;
  353.     head->head_len-=(int)sizeof(IMG_HEADER);
  354.  
  355.     if ( head->head_len>0 ) {
  356.         while ( head->head_len-- ) {
  357.             if ( (ret=get_byte(&byte))!=IMG_OK ) {
  358.                 Fclose(f_id);
  359.                 return ret;
  360.             }
  361.         }
  362.     }
  363.     else if ( head->head_len<0 ) {
  364.         Fclose(f_id);
  365.         return IMG_FORMAT;
  366.     }
  367.  
  368.     if ( head->plane_num>8 || head->pat_len>8 ) {
  369.         Fclose(f_id);
  370.         return IMG_FORMAT;
  371.     }
  372.  
  373.     picture->fd_h=head->scan_num;
  374.     picture->fd_nplanes=head->plane_num;
  375.     picture->fd_stand=1;
  376.     picture->fd_r1=picture->fd_r2=picture->fd_r3=0;
  377.  
  378.     line_len=head->pix_num/8;
  379.     if ( head->pix_num%8 )
  380.         line_len++;
  381.     picture->fd_wdwidth=line_len/2;
  382.     if ( line_len&1 )
  383.         picture->fd_wdwidth++;
  384.     
  385.     picture->fd_w=head->pix_num;
  386.  
  387.     len=(long)picture->fd_wdwidth*2*(long)head->scan_num*(long)head->plane_num;
  388.  
  389.     picture->fd_addr=malloc(len);
  390.     if ( picture->fd_addr==0l ) {
  391.         Fclose(f_id);
  392.         return IMG_MEMORY;
  393.     }
  394.  
  395.     llen=(long)head->pix_num*head->plane_num/8;
  396.     line_buf=malloc(llen);
  397.     if ( !line_buf ) {
  398.         Fclose(f_id);
  399.         return IMG_MEMORY;
  400.     }
  401.  
  402.     ret=do_ld_img(picture->fd_addr,line_buf,head);
  403.  
  404.     Fclose(f_id);
  405.     free(line_buf);
  406.     free(w_buf);
  407.  
  408.     return ret;
  409. }
  410.  
  411.  
  412. IMG_ERR xload_ximg(IMG_HEADER *head,char *name,MFDB *picture,IMG_COLOR **coltab)
  413. {
  414. IMG_ERR ret;
  415.  
  416.     ret=do_load_ximg(head,name,picture,coltab);
  417.     if ( ret!=IMG_OK ) {
  418.         if ( picture->fd_addr ) {
  419.             free(picture->fd_addr);
  420.             picture->fd_addr=0l;
  421.         }
  422.         if ( *coltab ) {
  423.             free(*coltab);
  424.             *coltab=0l;
  425.         }
  426.         if ( w_buf )
  427.             free(w_buf);
  428.     }
  429.     return ret;
  430. }
  431.  
  432. IMG_ERR xload_img(IMG_HEADER *head,char *name,MFDB *picture)
  433. {
  434. IMG_ERR ret;
  435.  
  436.     ret=do_load_img(head,name,picture);
  437.     if ( ret!=IMG_OK ) {
  438.         if ( picture->fd_addr ) {
  439.             free(picture->fd_addr);
  440.             picture->fd_addr=0l;
  441.         }
  442.         if ( w_buf )
  443.             free(w_buf);
  444.     }
  445.     return ret;
  446. }
  447.  
  448. IMG_ERR load_ximg(char *name,MFDB *picture,IMG_COLOR **coltab)
  449. {
  450. IMG_HEADER head;
  451.  
  452.     return xload_ximg(&head,name,picture,coltab);
  453. }
  454.  
  455. IMG_ERR load_img(char *name,MFDB *picture)
  456. {
  457. IMG_HEADER head;
  458.  
  459.     return xload_img(&head,name,picture);
  460. }
  461.